﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Common
{

    public class Transformation
    {
        #region CRC16校验
        /// <summary>
        /// CRC16校验算法,低字节在前，高字节在后
        /// </summary>
        /// <param name="data">要校验的数组</param>
        /// <returns>返回校验结果，低字节在前，高字节在后</returns>
        public static int[] crc16(int[] data)
        {
            if (data.Length == 0)
                throw new Exception("调用CRC16校验算法,（低字节在前，高字节在后）时发生异常，异常信息：被校验的数组长度为0。");
            int[] temdata = new int[data.Length + 2];
            int xda, xdapoly;
            int i, j, xdabit;
            xda = 0xFFFF;
            xdapoly = 0xA001;
            for (i = 0; i < data.Length; i++)
            {
                xda ^= data[i];
                for (j = 0; j < 8; j++)
                {
                    xdabit = (int)(xda & 0x01);
                    xda >>= 1;
                    if (xdabit == 1)
                        xda ^= xdapoly;
                }
            }
            temdata = new int[2] { (int)(xda & 0xFF), (int)(xda >> 8) };
            return temdata;
        }

        /// <summary>
        ///CRC16校验算法,（低字节在前，高字节在后）
        /// </summary>
        /// <param name="data">要校验的数组</param>
        /// <returns>返回校验结果，低字节在前，高字节在后</returns>
        public static byte[] crc16(byte[] data)
        {
            if (data.Length == 0)
                throw new Exception("调用CRC16校验算法,（低字节在前，高字节在后）时发生异常，异常信息：被校验的数组长度为0。");
            byte[] temdata = new byte[data.Length + 2];
            int xda, xdapoly;
            byte i, j, xdabit;
            xda = 0xFFFF;
            xdapoly = 0xA001;
            for (i = 0; i < data.Length; i++)
            {
                xda ^= data[i];
                for (j = 0; j < 8; j++)
                {
                    xdabit = (byte)(xda & 0x01);
                    xda >>= 1;
                    if (xdabit == 1)
                        xda ^= xdapoly;
                }
            }
            temdata = new byte[2] { (byte)(xda & 0xFF), (byte)(xda >> 8) };
            return temdata;
        }
        #endregion
        public static int DateToUTC()
        {
            DateTime TimeFormat = DateTime.Parse("1970-1-1 08:00:00");
            DateTime time = DateTime.Now;
            int lBeg = (int)time.Subtract(TimeFormat).TotalSeconds;
            return lBeg;
        }

        /// <summary>
        /// 字符串转16进制字节数组
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        public static byte[] strToToHexByte(string hexString)
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
                hexString += " ";
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }

        /// <summary>
        /// 字节数组转16进制字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string byteToHexStr(byte[] bytes)
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    returnStr += bytes[i].ToString("X2");
                }
            }
            return returnStr;

        }
        public static double HexToDouble(string hexString)
        {
            if (hexString == "")
            {

                return 0;

            }

            string data;

            if (hexString.StartsWith("0x"))
            {

                data = hexString.Substring(2);

            }

            else
            {

                data = hexString;

            }

            char[] eachData = data.ToCharArray();

            Double result = 0;

            for (int i = 0; i < eachData.Length; i++)
            {


                char charValue = eachData[i];//eachData[m];

                Double x = 16;//如果是八进制则写成8就可以

                Double y = System.Convert.ToDouble(eachData.Length - i - 1);

                switch (charValue)
                {

                    case '0':

                        break;

                    case '1':

                        result += 1 * Math.Pow(x, y);

                        break;

                    case '2':

                        result += 2 * Math.Pow(x, y);

                        break;

                    case '3':

                        result += 3 * Math.Pow(x, y);

                        break;

                    case '4':

                        result += 4 * Math.Pow(x, y);

                        break;

                    case '5':

                        result += 5 * Math.Pow(x, y);

                        break;

                    case '6':

                        result += 6 * Math.Pow(x, y);

                        break;

                    case '7':

                        result += 7 * Math.Pow(x, y);

                        break;

                    case '8':

                        result += 8 * Math.Pow(x, y);

                        break;

                    case '9':

                        result += 9 * Math.Pow(x, y);

                        break;

                    case 'A':

                        result += 10 * Math.Pow(x, y);

                        break;

                    case 'B':

                        result += 11 * Math.Pow(x, y);

                        break;

                    case 'C':

                        result += 12 * Math.Pow(x, y);

                        break;

                    case 'D':

                        result += 13 * Math.Pow(x, y);

                        break;

                    case 'E':

                        result += 14 * Math.Pow(x, y);

                        break;

                    case 'F':

                        result += 15 * Math.Pow(x, y);

                        break;

                    case 'a':

                        result += 10 * Math.Pow(x, y);

                        break;

                    case 'b':

                        result += 11 * Math.Pow(x, y);

                        break;

                    case 'c':

                        result += 12 * Math.Pow(x, y);

                        break;

                    case 'd':

                        result += 13 * Math.Pow(x, y);

                        break;

                    case 'e':

                        result += 14 * Math.Pow(x, y);

                        break;

                    case 'f':

                        result += 15 * Math.Pow(x, y);

                        break;

                    default:

                        break;

                }


            }

            return result;

        }

        /// <summary>
        /// 将二进制值转ASCII格式十六进制字符串
        /// </summary>
        /// <param name="data">二进制值</param>
        /// <param name="length">定长度的二进制</param>
        /// <returns>ASCII格式十六进制字符串</returns>
        public static string toHexString(int data, int length)
        {
            string result = "";
            if (data > 0)
                result = Convert.ToString(data, 16).ToUpper();
            if (result.Length < length)
            {
                // 位数不够补0
                StringBuilder msg = new StringBuilder(0);
                msg.Length = 0;
                msg.Append(result);
                for (; msg.Length < length; msg.Insert(0, "0")) ;
                result = msg.ToString();
            }
            return result;
        }

        /// <summary>
        /// 将浮点数转ASCII格式十六进制字符串（符合IEEE-754标准（32））
        /// </summary>
        /// <param name="data">浮点数值</param>
        /// <returns>十六进制字符串</returns>
        public static string floatToIntString(float data)
        {
            byte[] intBuffer = BitConverter.GetBytes(data);
            StringBuilder stringBuffer = new StringBuilder(0);
            for (int i = 0; i < intBuffer.Length; i++)
            {
                stringBuffer.Insert(0, toHexString(intBuffer[i] & 0xff, 2));
            }
            return stringBuffer.ToString();
        }

        /// <summary>
        /// 将ASCII格式十六进制字符串转浮点数（符合IEEE-754标准（32））
        /// </summary>
        /// <param name="data">十六进制字符串</param>
        /// <returns>浮点数值</returns>
        public static float intStringToFloat(String data)
        {
            if (data.Length < 8 || data.Length > 8)
            {
                //throw new NotEnoughDataInBufferException(data.length(), 8);
                throw (new ApplicationException("缓存中的数据不完整。"));
            }
            else
            {
                byte[] intBuffer = new byte[4];
                // 将16进制串按字节逆序化（一个字节2个ASCII码）
                for (int i = 0; i < 4; i++)
                {
                    intBuffer[i] = Convert.ToByte(data.Substring((3 - i) * 2, 2), 16);
                }
                return Convert.ToSingle(BitConverter.ToSingle(intBuffer, 0).ToString("F10"));
            }
        }
        public static byte[] stringToByteList(string str)
        {
            byte[] bt = new byte[str.Length];
            int i = 0;
            foreach (char j in str)
            {
                bt[i] = Convert.ToByte(j);
                i++;
            }
            return bt;
        }
        public static string byteListToString(byte[] bt)
        {
            string str = string.Empty;
            foreach (char i in bt)
            {
                str += Convert.ToChar(i);
            }
            return str;
        }
    }

}
